//生产者消费者问题
#include<iostream>
#include<thread>
#include<mutex>
#include<string>

#include<condition_variable>	//条件变量头文件
#include<queue>

std::queue<int> q_queue;
std::condition_variable q_cv;
std::mutex mtx;

void Producer()		//生产者
{
	for (int i = 0; i < 10; i++)
	{
		std::unique_lock<std::mutex> lock(mtx);
		q_queue.push(i);
		
		q_cv.notify_one();	//通知消费者线程取产品
		std::cout << "Producer: " << i << std::endl;
		
	}
	std::this_thread::sleep_for(std::chrono::microseconds(100));	//休眠100毫秒
}

void Consumer()
{
	while (1)
	{
		std::unique_lock<std::mutex> lock(mtx);

		//如果队列为空，等待
		//bool isempty = q_queue.empty();
		//q_cv.wait(lock, !isempty);		
		q_cv.wait(lock, []() {return !q_queue.empty();});		//改成lambda表达式
		int value = q_queue.front();
		q_queue.pop();

		std::cout <<"Consumer: " << value << std::endl;
	}
}



int main()
{
	std::thread t1(Producer);
	std::thread t2(Consumer);

	t1.join();
	t2.join();
	return 0;
}


/*
注意：
其中q_cv.wait()中第一个参数是一个unique_lock变量，第二个参数为一个bool，
若为false 则阻塞在此处，等待另一个线程q_cv.notify_one()或者q_cv.notify_all()去唤醒

condition_variable的wait会自动释放锁，直到被notify才会重新lock


在这种可以多个消费者取出的情况下，应该在取出前上锁，取出后解锁，对于数据的处理不要放在锁内。这里加括号只要是因为unique_lock是声明时上锁，析构时解锁不能使用lock和unlock函数手动上锁。
*/